/**
 * Mongo 
 *  目前仅提供简单的 mongo支持
 *      如需要 mongo的自动序列化，添加 mongoose 或者 typegoose
 */
import { IMongoConfig } from "../../etc/LyuInterface";
import { MongoClient, Db, Collection, MongoClientOptions } from "mongodb";

export default class LMongo extends MongoClient {
    private _db!: Db;
    private tbl!: string;
    private collection!: Collection;

    static async start(conf?: IMongoConfig) {
        let host = (conf && conf.host) || "localhost";
        let port = (conf && conf.port) || 27017;
        let db = (conf && conf.db) || "test";
        let table = (conf && conf.table);
        let m: LMongo;
        if (conf && conf.auth) {
            const uri = `mongodb://${conf.auth.username}:${conf.auth.password}@${host}:${port}/${db}?authSource=admin`;
            m = new LMongo(uri, {
                serverSelectionTimeoutMS: 5000  // 防止网络超时干扰诊断
            });
        } else {
            m = new LMongo(`mongodb://${host}:${port}/${db}`, {
                serverSelectionTimeoutMS: 5000  // 防止网络超时干扰诊断
            });
        }
        let lm = await m.connect();
        lm.select(db);
        if (table != undefined) {
            lm.table = table;
        }
        return lm
    }

    select(db: string) {
        this._db = this.db(db);
    }

    set table(tbl: string) {
        this.tbl = tbl;
        this.collection = this._db.collection(tbl);
    }
    get table() {
        return this.tbl;
    }

    // 获取内容 
    // keyObj: 查询条件 {name:"lyu"}
    async get(keyObj: any, tbl?: string) {
        if (tbl) {
            this.table = tbl;
        }
        return await this.collection.findOne(keyObj);
    }

    // 存储信息
    // obj: 存储对象 {name:"lyu", a: "xx", b "yy"}
    async set(obj: any, tbl?: string) {
        if (tbl) {
            this.table = tbl;
        }
        let insertObj = Object.assign({}, obj);
        await this.collection.insertOne(insertObj);
    }

    // 更新信息
    // key: 查询条件 {name:"lyu"}
    // set: 更新内容 {$set: {a: "xx", b "yy"}}
    async update(key: any, set: any, tbl?: string) {
        if (tbl) {
            this.table = tbl;
        }
        var whereStr = key;  // 查询条件
        let value = await this.get(key);
        if (value == null || value == undefined) {
            var updateStr = { $set: set };
            await this.collection.updateOne(whereStr, updateStr);
        } else {
            let obj = Object.assign(value, set);
            await this.set(obj);
        }
    }

    async getAll(key: any, tbl?: string) {
        if (tbl) {
            this.table = tbl;
        }
        return await this.collection.find(key).toArray();
    }

    async updateAll(key: any, set: any, tbl?: string) {
        if (tbl) {
            this.table = tbl;
        }
        var whereStr = key;
        var updateStr = { $set: set };
        await this.collection.updateMany(whereStr, updateStr);
    }


}